fix(eid-wallet): settle the settings store before the app is killed - #1149
Merged
Merged
Conversation
Closing the app from the background intermittently signed the user out,
dropping them back to the create-or-restore splash with their vault,
user, PIN and document gone.
The settings store is saved by tauri-plugin-store with fs::write, which
opens the file with O_TRUNC, so the previous contents are discarded
before the new bytes are written. Auto-save is debounced and Android
kills backgrounded apps with SIGKILL, so a save is frequently still in
flight when the kill lands. Interrupting that write leaves
global-state.json at zero bytes, and the next launch reads an empty
store, concludes this is a first run and persists a fresh onboarding
state over the top, which makes the loss permanent.
An app is only killed after it has been backgrounded, and the webview
still receives visibilitychange at that point. Use it as the settling
point: flush the store so no debounced write remains outstanding, then
copy the settled file into a sidecar backup written atomically via a
temp file, fsync and rename. Once that completes there is no write left
for a kill to interrupt.
Loading falls back to the sidecar when the primary file cannot be
parsed, which covers a kill that arrives before the flush finishes; the
backup then still holds the previous complete state. Recovery keys off
unparseable bytes rather than an absent or empty cache, so a session the
user ended deliberately is never resurrected: clearing the store on
logout serialises to "{}", which is valid JSON and is passed through
untouched. Backing up refuses to copy a primary that does not parse, so
a damaged file cannot overwrite a good backup. With no readable backup
the original parse error is returned and a genuine first launch still
runs normal setup instead of receiving invented state.
All of this runs at backgrounding only. The startup and steady-state
save paths are untouched, so launch performs no extra filesystem work.
Fixes #1143
Contributor
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Bekiboo
reviewed
Sep 23, 2026
Bekiboo
left a comment
Collaborator
There was a problem hiding this comment.
Audit pass. None of these are blocking.
Sahil2004
force-pushed
the
fix/bug-eid-wallet-intermittent-logout
branch
from
September 24, 2026 04:25
d6090ef to
17bc482
Compare
The backup is a copy of the store as it was at the last backgrounding, so between a reset and the next backgrounding it still held the user, vault and PIN hash of the session that just ended. Recovery keys off unparseable bytes, so a kill that truncated the primary file in that window restored the backup and brought the ended session back with its credentials intact. Settle the cleared store and refresh the backup as part of the reset, which bounds that window to the reset itself. The refresh sits outside the catch so a controller that throws part-way through clearing cannot leave the stale copy behind.
Sahil2004
force-pushed
the
fix/bug-eid-wallet-intermittent-logout
branch
from
September 24, 2026 04:35
17bc482 to
b8c6095
Compare
Bekiboo
approved these changes
Sep 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description of change
Closing the app from the background intermittently signed the user out, dropping them back to the create-or-restore splash with their vault, user, PIN and document gone.
The settings store is saved by tauri-plugin-store with fs::write, which opens the file with O_TRUNC, so the previous contents are discarded before the new bytes are written. Auto-save is debounced and Android kills backgrounded apps with SIGKILL, so a save is frequently still in flight when the kill lands. Interrupting that write leaves global-state.json at zero bytes, and the next launch reads an empty store, concludes this is a first run and persists a fresh onboarding state over the top, which makes the loss permanent.
An app is only killed after it has been backgrounded, and the webview still receives visibilitychange at that point. Use it as the settling point: flush the store so no debounced write remains outstanding, then copy the settled file into a sidecar backup written atomically via a temp file, fsync and rename. Once that completes there is no write left for a kill to interrupt.
Loading falls back to the sidecar when the primary file cannot be parsed, which covers a kill that arrives before the flush finishes; the backup then still holds the previous complete state. Recovery keys off unparseable bytes rather than an absent or empty cache, so a session the user ended deliberately is never resurrected: clearing the store on logout serialises to "{}", which is valid JSON and is passed through untouched. Backing up refuses to copy a primary that does not parse, so a damaged file cannot overwrite a good backup. With no readable backup the original parse error is returned and a genuine first launch still runs normal setup instead of receiving invented state.
All of this runs at backgrounding only. The startup and steady-state save paths are untouched, so launch performs no extra filesystem work.
Issue Number
Closes #1143
Type of change
How the change has been tested
Manually.
Change checklist